package thread;
/*** 有效的缩小同步范围可以在保证并发安全的前提下尽可能的提高并发效率.
 * 同步块:
 * synchronized(同步监视器对象){
 *     需要同步执行的代码片段
 * }*/
public class SyncDemo2 {
    public static void main(String[] args) {
        Shop shop = new Shop();
//        Shop shop2 = new Shop();  不是同一个临界资源
        Thread t1 = new Thread("小红"){
            @Override
            public void run() {
                shop.buy();
            }
        };
        Thread t2 = new Thread("小明"){
            @Override
            public void run() {
                shop.buy();
            }
        };
        t1.start();
        t2.start();
    }
}
class Shop{
    /**
     * 成员方法中使用synchronized,同步监视器对象不可选,就是this*/
    public void buy(){
        try {
            Thread thread = Thread.currentThread();//tread是当前执行代码的线程
            System.out.println(thread.getName()+"挑衣服....");
            Thread.sleep(3000);
            /*同步块使用时必须在synchronized()中指定同步监视器对象,该对象必须满足两点:
            * 1.必须是引用类型的实例
            * 2.多个线程看到的必须是同一个对象
            * 合适的锁对象除了满足上述两点外,还应当满足同步时多个线程看到的是同一对象,不该同步时看到的是不同对象*/
            synchronized (this){//this:shop   "" 也是同一个对象
//            synchronized (thread){//thread是当前执行代码的线程,不同线程thread表示的不同,因此不可以
//            synchronized (new Object()){//new一定产生新对象,因此一定不能作为同步监视器使用
                System.out.println(thread.getName()+"试衣服....");
                Thread.sleep(6000);
            }
            System.out.println(thread.getName()+"结账离开...");
            /*synchronized (this){
                System.out.println(thread.getName()+"结账离开...");
                Thread.sleep(3000);
            }*/

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}
